uses x,xlib,xutil;

function AllWndProc(H:DWord;msg:DWord;wprm:LongInt;lprm:LongInt):longint;{$ifndef virtualpascal}stdcall;{$endif}//fake
begin
end;

{ TWinControl }

function TWinControl.GetRealWindow: boolean;
begin
  //to be overriden
  Result:=false;//by default for "widgets"
end;

procedure TWinControl.SetLeft(AValue: integer);

begin
  inherited SetLeft(AValue);
  if not RealWindow then exit;
  if FHandle<>0 then XMoveWindow(XWinDisplay,FHandle,FLeft,FTop);
end;

procedure TWinControl.SetTop(AValue: integer);
begin
  inherited SetTop(AValue);
  if not RealWindow then exit;
  if FHandle<>0 then XMoveWindow(XWinDisplay,FHandle,FLeft,FTop);
end;

procedure TWinControl.SetWidth(AValue: integer);
begin
  inherited SetWidth(AValue);
  if not RealWindow then exit;
  if FHandle<>0 then XResizeWindow(XWinDisplay,FHandle,FWidth,FHeight);

end;

procedure TWinControl.SetHeight(AValue: integer);
begin
  inherited SetHeight(AValue);
  if not RealWindow then exit;
  if FHandle<>0 then XResizeWindow(XWinDisplay,FHandle,FWidth,FHeight);
end;




procedure TWinControl.SetParent(AValue: TComponent);
var
  ParHan: THandle;
  Messg: mSets.TMessage;
  event_mask: Integer;
begin
  inherited SetParent(AValue);
  if Parent=nil then exit;
  if not (Parent is TWinControl) then exit;
  ParHan:=(Parent as TWinControl).Handle;
  if ParHan=0 then exit;
  if FSpecificHandling then exit;//Not here
  if FWinCreated then //TODO: Reparent
  else
  begin
    FHandle:=XCreateSimpleWindow(XWinDisplay,ParHan,FLeft,FTop,FWidth,FHeight,0,clWhite,clWhite);
        event_mask:=KeyPressMask or KeyReleaseMask or EnterWindowMask or
      LeaveWindowMask or PointerMotionHintMask or Button1MotionMask or Button2MotionMask
      or Button3MotionMask or VisibilityChangeMask or StructureNotifyMask or ButtonPressMask or
      ButtonReleaseMask;
    XSelectInput(XWinDisplay,FHandle,event_mask);
    AllWnds.Add(self);
  end;
end;

procedure TWinControl.Show;
begin
  inherited Show;
  if not RealWindow then exit;
  if FHandle=0 then exit;
  XMapRaised(XWinDisplay,FHandle);

  if Handle<>0 then if FCanvas.Handle<>0 then FCanvas.ActualizeWin(FHandle);
end;

destructor TWinControl.Destroy;
var
  i: Integer;
begin
  inherited Destroy;
  FCanvas.Free;

  i:=AllWnds.IndexOf(self);
  if i<>-1 then AllWnds.Delete(i);
end;

procedure TControl.ProcessEvent(Ev: pointer);
var
    Evnt:PXEvent absolute ev;
    MEvent:PXMotionEvent absolute Evnt;
    BPEvent:PXButtonEvent absolute Evnt;
    KEvent:PXKeyEvent absolute Evnt;
    REvent:PXResizeRequestEvent absolute Evnt;
    CfgEvent:PXConfigureEvent absolute Evnt;
    Msg:TMessage;
begin
  //May be somewhat usefull under win, but not now
  Msg.Result:=1;
  case Evnt^._type of
    MotionNotify,ButtonPress,ButtonRelease,EnterNotify:
                 begin
                   //if not (Evnt^._type=MotionNotify) then writeln('Mouse event');
                   Msg.LParamLo:=MEvent^.x_root;
                   Msg.LParamHi:=MEvent^.y_root;
                   if (Evnt^._type=MotionNotify) or (Evnt^._type=EnterNotify) then Msg.MSG:=wm_MouseMove else
                   if (Evnt^._type=ButtonPress) then
                   begin
                     if BPEvent^.button=Button1 then Msg.MSG:=wm_LButtonDown
                     else if BPEvent^.button=Button3 then Msg.MSG:=wm_RButtonDown
                     else if BPEvent^.button=Button2 then Msg.MSG:=wm_MButtonDown;
                   end;
                   if (Evnt^._type=ButtonRelease) then
                   begin
                     if BPEvent^.button=Button1 then Msg.MSG:=wm_LButtonUp
                     else if BPEvent^.button=Button3 then Msg.MSG:=wm_RButtonUp
                     else if BPEvent^.button=Button2 then Msg.MSG:=wm_MButtonUp;
                   end;
                   Msg.WParam:=0;
                   if (MEvent^.state and ControlMask)<>0 then Msg.WParam:=mk_Control;
                   if (MEvent^.state and ShiftMask)<>0 then Msg.WParam:=mk_Shift;
                   if (MEvent^.state and Button1Mask)<>0 then Msg.WParam:=Msg.WParam or mk_LButton;
                   if (MEvent^.state and Button2Mask)<>0 then Msg.WParam:=Msg.WParam or mk_MButton;
                   if (MEvent^.state and Button3Mask)<>0 then Msg.WParam:=Msg.WParam or mk_RButton;
                   Dispatch(Msg);
                   exit;
                 end;
    KeyPress,KeyRelease:
                 begin
                   //1. We won't use LParam. It is very special for Windows, not for unix
                   //2. We won't translate any KeyCodes. It is system default, a better way
                   //   is to make key constants vary from OS
                   Msg.WParam:=KEvent.keycode;
                   if Evnt^._type=KeyPress then Msg.MSG:=wm_KeyDown else Msg.MSG:=wm_KeyUp;
                   Dispatch(Msg);
                   exit;
                 end;
    CreateNotify:begin
                   Msg.MSG:=wm_Create;
                   //We need nothing more!
                   Dispatch(Msg);
                   exit;
                 end;
    DestroyNotify:begin
                   Msg.MSG:=wm_Close;
                   Dispatch(Msg);
                   Msg.MSG:=wm_Destroy;
                   Msg.Result:=1;
                   Dispatch(Msg);
                   exit;
                  end;
    MapNotify,UnmapNotify:
                 begin
                   Msg.MSG:=wm_ShowWindow;
                   Msg.WParam:=LongInt(LongBool(Evnt._type=MapNotify));
                   FShownFirst:=true;
                   Dispatch(Msg);
                   Msg.MSG:=wm_paint;
                   Msg.Result:=-1;
                   Dispatch(MSG);
                   exit;
                 end;
    LeaveNotify: begin
                    Msg.WParam:=0;Msg.LParam:=0;
                    Msg.MSG:=wm_MouseLeave;

                    Dispatch(Msg);
                    exit;

                  end;
    VisibilityNotify:
                 begin
                   if not FShownFirst then exit;
                   Msg.MSG:=wm_paint;
                   msg.WParam:=0;Msg.LParam:=0;//TODO, but now we redrawing all
                   Dispatch(Msg);
                   exit;
                 end;
    ConfigureNotify:
                 begin
                   Msg.MSG:=wm_Size;
                   Msg.LParamLo:=CfgEvent^.width;
                   Msg.LParamHi:=CfgEvent^.height;
                   Dispatch(Msg);
                   if not FShownFirst then exit;
                   Msg.Msg:=wm_paint;
                   Msg.Result:=1;
                   Dispatch(Msg);
                   exit;
                 end;
  end;
  //writeln('... not processed');
end;
procedure InitMCTrl;
begin
end;
